/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * 
 * Project Name:itsm-gateway
 * Create Time: 2016年2月15日 上午11:40:28
 */
package com.lenovo.lmrp.server.itsmgateway.domain.ticket;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lenovo.lmrp.api.constant.TicketPriority;
import com.lenovo.lmrp.api.model.entity.TicketPO;
import com.lenovo.lmrp.api.model.entity.TicketPartsPO;
import com.lenovo.lmrp.api.model.entity.TicketPartsPO.PartsAction;
import com.lenovo.lmrp.api.model.view.ChangedTicketVO;
import com.lenovo.lmrp.api.model.view.PartsVO;
import com.lenovo.lmrp.api.model.view.TicketVO;
import com.lenovo.lmrp.server.itsmgateway.adapter.AItsmAdapter;
import com.lenovo.lmrp.server.itsmgateway.domain.metadata.ItsmEntityTranslator;
import com.lenovo.lmrp.server.itsmgateway.domain.metadata.ItsmEntityTranslator.EntityName;
import com.lenovo.sdc.framework.util.JSONHelper;
import com.lenovo.sdc.framework.util.Tuple;

/**
 * 
 * @author wujin
 * @version v1.0
 */
public class TicketBO {
    private static final Logger logger = LoggerFactory.getLogger(TicketBO.class);
    
    private String itsmCode;
    private TicketPO ticketPO;
    private boolean isdirty;
    private List<TicketPartsPO> ticketPartsList;
    
    private AItsmAdapter adapter;
    
    public TicketBO(AItsmAdapter adapter, String itsmCode, TicketPO ticketPO) {
        this.itsmCode = itsmCode;
        this.ticketPO = ticketPO;
        this.adapter = adapter;
        
        this.isdirty = false;
    }
    
    /**
     * submit parts for this ticket
     * 
     * @param partsList
     * @return
     */
    public Tuple.Pair<Boolean, String> addParts(List<PartsVO> partsList) {
        if (Objects.isNull(ticketPartsList))
            ticketPartsList = new ArrayList<>();
        
        for(PartsVO vo : partsList) {
            TicketPartsPO partsPO = new TicketPartsPO();
            partsPO.setTicketId(ticketPO.getId());
            partsPO.setFRU(vo.getFru());
            partsPO.setId(vo.getPartsnum());
            partsPO.setName(vo.getPartsname());
            partsPO.setType(vo.isNew() ? PartsAction.UP : PartsAction.DOWN);
            partsPO.setDescription(vo.getDescription());
            ticketPartsList.add(partsPO);
        }
        
        Tuple.Pair<Boolean, String> result = adapter.replaceParts(ticketPO.getId(), partsList);
        isdirty = true;
        
        return result;
    }
    
    /**
     * update ticket properties, invoke certain adapter to notify ITSM system
     * 
     * @param action
     * @param reason
     * @param fields
     * @return
     */
    public boolean update(String action, String reason, Map<String, String> fields) {
        ticketPO.getOthers().getAttributeBean().addAttribute("reason", reason);
        
        ChangedTicketVO vo = new ChangedTicketVO();
        vo.setFields(fields);
        vo.setTicketid(ticketPO.getId());
        vo.setAction(action);
        vo.setReason(reason);
        Tuple.Pair<Boolean, String> resp = adapter.updateTicket(vo);
        
        ItsmEntityTranslator translator = new ItsmEntityTranslator();
        Map<String, Object> result = translator.translateValue(itsmCode, EntityName.TICKET, fields);
        for(Map.Entry<String, Object> entry : result.entrySet()) {
            ticketPO.getOthers().getAttributeBean().addAttribute(entry.getKey(), entry.getValue());
        }
        isdirty = true;
        return resp.getOne();
    }
    
    public void store(ITicketRepository repository) {
        if (isdirty) {
            if (Objects.nonNull(ticketPartsList))
                repository.storeTicketParts(itsmCode, ticketPartsList);
            
            repository.storeTicketWithExtense(itsmCode, ticketPO);
        }
        
        isdirty = false;
    }
    
    /**
     * create new TicketVO object wrap po object fields
     */
    public TicketVO getTicketVO() {
        TicketVO vo = new TicketVO();
        vo.setTicketid(ticketPO.getId());
        vo.setTitle(ticketPO.getCaption());
        vo.setPriority(TicketPriority.get(ticketPO.getPriority()).getDescr());
        vo.setProject(ticketPO.getProjectId());
        vo.setcTime(ticketPO.getCreateTime());
        vo.setState(ticketPO.getStatus());
        if (Objects.nonNull(ticketPO.getOthers())) {
            try {
                vo.setOthers(JSONHelper.fromJSON(ticketPO.getOthers().getExtprops(), Map.class));
            }
            catch (Exception exp) {
                logger.error("", exp);
            }
        }
        return vo;
    }
    
    public void updateTicketExtense(ITicketRepository repository,Map<String, Object> newExtense) {
    	for(Map.Entry<String, Object> entry : newExtense.entrySet()) {
            ticketPO.getOthers().getAttributeBean().addAttribute(entry.getKey(), entry.getValue());
        }
    	repository.storeTicketOnlyExtense(itsmCode, ticketPO);
    }
}
